#include <iostream>
#include <cstdlib>
#include "d_Math.h"

using namespace d_Math;

d_Matf::d_Matf(int n, int m)
{
	this->n = n;
	this->m = m;
	p = (float **) malloc(n*sizeof(float *));
	for(int i=0; i<n; i++)
		p[i] = (float *) malloc(m*sizeof(float));
	for(int i=0; i<n; i++) 
		for(int j=0; j<m; j++)
			p[i][j] = 0;
}

void d_Matf::transpose(d_Matf& T)
{
	for(int i=0; i<m; i++)
		for(int j=0; j<n; j++)
			T(i,j) = p[j][i];
}

void d_Matf::print()
{
	std::cout << "[";
	for(int i=0; i<n; i++)
	{
		std::cout << "[ ";
		for(int j=0; j<m; j++)
		{
			std::cout << p[i][j] << " ";
		}
		std::cout << "]";
		if(i!=n-1)
			std::cout << std::endl;
	}
	std::cout << "]" << std::endl;
}

d_Matf d_Matf::operator * (d_Matf M)
{
	d_Matf R(m,n);

	for(int k=0; k<m; k++)
		for(int l=0; l<n; l++)
		{
			for(int i=0; i<n; i++)
				R(k,l)+=p[k][i]*M(i,l); 
		}

	return R;
}

float &d_Matf::operator () (int ir, int ic)
{ 
	if(ir>n || ic>m)
	{
		std::cout << "Bad index for matrix!" << std::endl;
		return p[0][0];
	}
	return p[ir][ic]; 
}

float d_Matf::operator () (int ir, int ic) const
{ 
	if(ir>n || ic>m)
	{
		std::cout << "Bad index for matrix!" << std::endl;
		return p[0][0];
	}
	return p[ir][ic]; 
}

void d_Matf::set(int i, int j, float value)
{
	p[i][j] = value;
}

float d_Matf::get(int i, int j)
{
	return p[i][j];
}

d_Vecf d_Matf::operator * (d_Vecf v)
{
	d_Vecf result;
	if(m!=v.get_size())
	{
		std::cout << "Can't realize matrix operation! bad sizes!" << std::endl;
	}
	
	result.set_size(m);
	for(int i=0; i<m; i++)
		for(int j=0; j<n; j++)
			result[i] += p[i][j]*v[j];
	return result;
}


